From: Aadhu23 Date: Sat, 19 Sep 2026 09:07:54 +0000 (+0800) Subject: videoio: fix build with FFmpeg 9 after AVCodec::pix_fmts and supported_framerates... X-Git-Tag: archive/raspbian/4.10.0+dfsg-9+rpi1^2~1 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=68f4af058fdc40c4763f721c929907649e264e7c;p=opencv.git videoio: fix build with FFmpeg 9 after AVCodec::pix_fmts and supported_framerates removal FFmpeg 9 removes AVCodec::pix_fmts and AVCodec::supported_framerates, which were deprecated in FFmpeg 7.1 (libavcodec 61.13.100) in favour of avcodec_get_supported_config(). Query both lists through avcodec_get_supported_config() when building against libavcodec 61.13.100 or newer; that call also reports the number of entries, so the loops iterate by count instead of relying on the old sentinel terminator. FFmpeg older than 7.1 keeps the previous direct field access. The ffmpeg 7.1 in trixie and 8.x in unstable already take the new code path. . Backport of the three commits of upstream PR #29533 (merged into the 4.x branch on 2026-08-11, not yet in any release tag), ported by hand because 4.10.0 predates later 4.x changes to these files: . https://github.com/opencv/opencv/commit/700cd32ffd59ed3c6f6aec1919867653d8b125ea https://github.com/opencv/opencv/commit/83ed22ca2800267050a4a9a94afab605c990c0e0 https://github.com/opencv/opencv/commit/c0166c617d765ac707dde6b9acd8cfcd49751049 Origin: backport, https://github.com/opencv/opencv/pull/29533 Bug: https://github.com/opencv/opencv/issues/29504 Bug: https://github.com/opencv/opencv/issues/29655 Bug-Debian: https://bugs.debian.org/1144031 Forwarded: not-needed Reviewed-by: Aron Xu Last-Update: 2026-09-19 Gbp-Pq: Name ffmpeg-9.0-compat.patch --- diff --git a/modules/videoio/src/cap_ffmpeg_hw.hpp b/modules/videoio/src/cap_ffmpeg_hw.hpp index 0998ee9..2ecdc55 100644 --- a/modules/videoio/src/cap_ffmpeg_hw.hpp +++ b/modules/videoio/src/cap_ffmpeg_hw.hpp @@ -738,6 +738,30 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor #endif if (hw_type == AV_HWDEVICE_TYPE_CUDA) // CUDA encoders don't support avcodec_get_hw_config() hw_native_fmt = AV_PIX_FMT_CUDA; +#if LIBAVCODEC_BUILD >= AV_VERSION_INT(61, 13, 100) + if (av_codec_is_encoder(c) && hw_native_fmt != AV_PIX_FMT_NONE) { + const AVPixelFormat *pix_fmts = NULL; + int num_pix_fmts = 0; + + int ret = avcodec_get_supported_config( + NULL, + c, + AV_CODEC_CONFIG_PIX_FORMAT, + 0, + (const void **)&pix_fmts, + &num_pix_fmts); + + if (ret >= 0 && pix_fmts && num_pix_fmts > 0) { + for (int i = 0; i < num_pix_fmts; i++) { + if (pix_fmts[i] == hw_native_fmt) { + *hw_pix_fmt = hw_native_fmt; + if (hw_check_codec(c, hw_type, disabled_codecs)) + return c; + } + } + } + } +#else if (av_codec_is_encoder(c) && hw_native_fmt != AV_PIX_FMT_NONE && c->pix_fmts) { for (int i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { if (c->pix_fmts[i] == hw_native_fmt) { @@ -747,6 +771,7 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor } } } +#endif for (int i = 0;; i++) { const AVCodecHWConfig *hw_config = avcodec_get_hw_config(c, i); if (!hw_config) diff --git a/modules/videoio/src/cap_ffmpeg_impl.hpp b/modules/videoio/src/cap_ffmpeg_impl.hpp index 1128803..393b1c8 100644 --- a/modules/videoio/src/cap_ffmpeg_impl.hpp +++ b/modules/videoio/src/cap_ffmpeg_impl.hpp @@ -2292,6 +2292,38 @@ static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc, c->time_base.den = frame_rate; c->time_base.num = frame_rate_base; /* adjust time base for supported framerates */ +#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(61, 13, 100) + if (codec){ + const AVRational *supported_framerates = NULL; + int num_supported_framerates = 0; + int ret = avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_FRAME_RATE, 0, + (const void **)&supported_framerates, &num_supported_framerates); + + if (ret >= 0 && supported_framerates && num_supported_framerates > 0){ + AVRational req = {frame_rate, frame_rate_base}; + const AVRational *best=NULL; + AVRational best_error= {INT_MAX, 1}; + for(int i = 0; i < num_supported_framerates; i++){ + const AVRational *p = &supported_framerates[i]; + AVRational error = av_sub_q(req, *p); + if(error.num <0) error.num *= -1; + if(av_cmp_q(error, best_error) < 0){ + best_error = error; + best = p; + } + } + if (best == NULL) + { +#ifdef CV_FFMPEG_CODECPAR + avcodec_free_context(&c); +#endif + return NULL; + } + c->time_base.den = best->num; + c->time_base.num = best->den; + } + } +#else if(codec && codec->supported_framerates){ const AVRational *p= codec->supported_framerates; AVRational req = {frame_rate, frame_rate_base}; @@ -2315,6 +2347,7 @@ static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc, c->time_base.den= best->num; c->time_base.num= best->den; } +#endif c->gop_size = 12; /* emit one intra frame every twelve frames at most */ c->pix_fmt = pixel_format;